using System;
using System.Text.RegularExpressions;
using System.IO;
using System.Diagnostics;
using System.Net;
using System.Text;
namespace FSHelperLib {
	// clarification from http://www.dotnetsmart.com/forums/2866/ShowPost.aspx
	//    System.Web.HttpRequest is a class used on the server and inside an ASP.NET application. It represents the *incoming* request from a client.
	//   System.Net.HttpWebRequest is a class used to make an *outgoing request to a web application.
	//The best ideas come from http://odetocode.com/Articles/162.aspx
	///<summary>
	/// Summary description for HttpWebRequestHelper.
	///</summary>
	public class HttpWebRequestHelper {
		static void MainX() {
		}
		// Methods
		public HttpWebRequestHelper() {
		}
		//only cookies returned, actual response is ignored
		public static CookieContainer PostWithCookies(string sUrl,string postData,string saveHtml) {
			// have a cookie container ready to receive the forms auth cookie
			CookieContainer cntnrCookies=new CookieContainer();
			return PostWithCookies(sUrl,postData,saveHtml,ref cntnrCookies);
		}
		//only cookies returned, actual response is ignored
		public static CookieContainer PostWithCookies(string sUrl,string postData,string saveHtml,ref CookieContainer cntnrCookies) {
			if(cntnrCookies==null)
			{
				cntnrCookies=new CookieContainer();
			}
			HttpWebResponse resp=PostGetHttpWebResponse(sUrl,postData,ref cntnrCookies);
			Debug.WriteLine(" resp.ResponseURI="+resp.ResponseUri);
			Stream strmResponse=resp.GetResponseStream();
			//if(!string.IsNullOrEmpty(saveHtml))
			//  StreamHelper.SaveToFile(strmResponse,saveHtml);
			//DebugHelper.PrintCookies(new Uri(sUrl),cntnrCookies);
			return cntnrCookies;
		}
		public static HttpWebResponse PostGetHttpWebResponse(string sUrl,string postData,ref CookieContainer cntnrCookies) {
			//from http://odetocode.com/Articles/162.aspx
			HttpWebRequest webRequest=PreparePostRequest(sUrl,postData,cntnrCookies);
			HttpWebResponse resp=webRequest.GetResponse() as HttpWebResponse;
			//from http://www.codeproject.com/csharp/clientticket_msnp9.asp
			while((resp.StatusCode==HttpStatusCode.Redirect))//add? || (resp.StatusCode == HttpStatusCode.Moved ) )
			{// If the statuscode is 302, then there is a redirect, read the new adres en connect again
				string uri=resp.Headers.Get("Location");
				// Make a new request
				webRequest=(HttpWebRequest)HttpWebRequest.Create(uri); //get, not post
				webRequest.CookieContainer=cntnrCookies;
				//try to change extra options if required - from http://www.codeproject.com/csharp/ClientTicket_MSNP9.asp         
				resp=(HttpWebResponse)webRequest.GetResponse();
			}
			//DebugHelper.PrintHttpWebResponse(resp,TraceHelper.LineWithTrace(""));
			//DebugHelper.PrintCookies(webRequest.RequestUri,cntnrCookies);
			//DebugHelper.PrintCookies(resp.Cookies,"Response.Cookies" );
			return resp;
		}
		private static HttpWebRequest PreparePostRequest(string sUrl,string postData,CookieContainer cntnrCookies) {
			//from http://odetocode.com/Articles/162.aspx
			// first, request the login form to get the viewstate value
			// now post to the login form
			HttpWebRequest webRequest=PrepareWebRequest(sUrl,"POST",cntnrCookies);
			// write the form values into the request message
			StreamWriter requestWriter=new StreamWriter(webRequest.GetRequestStream());
			requestWriter.Write(postData);
			requestWriter.Close();
			return webRequest;
		}
		//The Method property can be set to any of the HTTP 1.1 protocol verbs: GET, HEAD, POST, PUT, DELETE, TRACE, or OPTIONS.
		public static HttpWebRequest PrepareWebRequest(string sUrl,string Method,CookieContainer cntnrCookies) {
			HttpWebRequest webRequest=WebRequest.Create(sUrl) as HttpWebRequest;
			webRequest.Method=Method;
			webRequest.ContentType="application/x-www-form-urlencoded";
			webRequest.CookieContainer=cntnrCookies;
			/*                //try to change - from http://www.codeproject.com/csharp/ClientTicket_MSNP9.asp         
									webRequest.AllowAutoRedirect = false;
								 webRequest.Pipelined = false;
									webRequest.KeepAlive = false;
									webRequest.ProtocolVersion = new Version(1,0);//protocol 1.0 works better that 1.1 ??
			*/
			//MNF 26/5/2005 Some web servers expect UserAgent to be specified
			//so let's say it's IE6
			webRequest.UserAgent="Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; .NET CLR 1.1.4322)";
			//DebugHelper.PrintHttpWebRequest(webRequest,TraceHelper.LineWithTrace(""));
			return webRequest;
		}
		public static string PostGetResponseString(string sUrl,string postData,ref CookieContainer cntnrCookies,string saveHtml) {
			HttpWebResponse resp=PostGetHttpWebResponse(sUrl,postData,ref cntnrCookies);
			string sResp=GetResponseString(resp,saveHtml);
			return sResp;
		}
		/// <summary>
		///
		/// </summary>
		/// <param name="sUrl"></param>
		/// <param name="Method"> verbs: GET, HEAD, POST, PUT, DELETE,TRACE, or OPTIONS.</param>
		/// <param name="cntnrCookies">can be null </param>
		/// <param name="sFileToSaveHtml">specify null, if in production</param>
		/// <returns></returns>
		/// <example>
		/// HttpWebRequestHelper.GetResponseString ("https://MySite/default.aspx?EntryPoint=1111", "GET", null, "temp.htm");
		/// </example>
		public static string GetResponseString(string sUrl,string Method,CookieContainer cntnrCookies,string sFileToSaveHtml) {
			HttpWebRequest webRequest=HttpWebRequestHelper.PrepareWebRequest(sUrl,Method,cntnrCookies);
			HttpWebResponse resp=webRequest.GetResponse() as HttpWebResponse;
			return HttpWebRequestHelper.GetResponseString(resp,sFileToSaveHtml);
		}
		public static string GetResponseString(HttpWebResponse resp,string saveHtml) {
			string sResp=new StreamReader(resp.GetResponseStream()).ReadToEnd();
			resp.Close();
			//if(!DataHelper.IsNullOrEmpty(saveHtml))
			//StreamHelper.SaveStringToFile(sResp,saveHtml);
			return sResp;
		}
		public static bool CookieExists(string sUrl,CookieContainer container,string name) {
			return CookieExists(new Uri(sUrl),container,name);
		}
		public static bool CookieExists(Uri uri,CookieContainer container,string name) {
			if(container==null)
			{
				return false;
			}
			System.Net.CookieCollection cookies=container.GetCookies(uri);
			return CookieExists(cookies,name);
		}
		public static bool CookieExists(CookieCollection cookies,string name) {
			return (cookies[name]!=null);
		}
		public static string ExtractViewState(string sHtml) { //another implementation is in http://odetocode.com/Articles/162.aspx
			string sRet="";
			try
			{
				String sPattern=@"name=""__VIEWSTATE"".value=""(.*?)""";// name="__VIEWSTATE".value="(.*?)"
				sRet=System.Text.RegularExpressions.Regex.Match(sHtml,sPattern).Groups[1].Value;
				//can return empty viewstate
				//if (String.IsNullOrEmpty(sRet))
				//{
				//    throw new FSCSharpLib.ExceptionWithDetails("The returned html has unexpected format", "html: " + sHtml);
				//}
			}
			catch(Exception exc)
			{
				throw new Exception("The returned html has unexpected format, html: "+sHtml,exc);
			}
			//From http://odetocode.com/Articles/162.aspx:
			//Notice the use of URL encoding to make sure the server misinterprets no characters with a special meaning (like the equal sign).
			return System.Web.HttpUtility.UrlEncodeUnicode(sRet);
		}
		//Default method is Get, do not store cookies
		public static Stream GetResponseStream(string sUrl,IWebProxy proxy) {
			HttpWebRequest webRequest=WebRequest.Create(sUrl) as HttpWebRequest;
			// webRequest.ContentType = "application/x-www-form-urlencoded";//is good?
			webRequest.Proxy=proxy;
			//you can change some properties if required - from http://www.codeproject.com/csharp/ClientTicket_MSNP9.asp         
			//MNF 26/5/2005 Some web servers expect UserAgent to be specified,so let's say it's IE6
			webRequest.UserAgent="Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; .NET CLR 1.1.4322)";
			//DebugHelper.PrintHttpWebRequest(webRequest,TraceHelper.LineWithTrace(""));
			HttpWebResponse resp=webRequest.GetResponse() as HttpWebResponse;
			Stream strm=resp.GetResponseStream();
			return strm;//'HttpWebRequestHelper.GetResponseString(resp, sFileToSaveHtml);
		}
	}// class HttpWebRequestHelper
}